﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "SectionViewSymbolNewBehaviors.h"
#include "AlgorithmProject.h"
#include "AuxiliaryElementUtils.h"
#include "DbObjectUtils.h"
#include "GbmpBuiltInCategoryUniIdentitiesNew.h"
#include "GbmpModelViewUtil.h"
#include "GcmpBuiltInCategoryUniIdentities.h"
#include "GcmpBuiltInParameterDefinitions.h"
#include "GraphicsRenderLayer.h"
#include "ICalculator.h"
#include "ICalculatorCollection.h"
#include "IDocument.h"
#include "IElement.h"
#include "IElementModelShape.h"
#include "IElementMoveContext.h"
#include "IElementParameters.h"
#include "IElementParentReporter.h"
#include "IElementPositionPoints.h"
#include "IElementStatus.h"
#include "IGenericElement.h"
#include "IGraphicsElementShape.h"
#include "IGraphicsLine.h"
#include "IGraphicsPoint.h"
#include "IGraphicsStyleManager.h"
#include "IModelView.h"
#include "IViewClipRange.h"
#include "IParameter.h"
#include "IParameterDefinitionLibrary.h"
#include "IPlane.h"
#include "IRegenerator.h"
#include "RegenDataId.h"
#include "SectionViewSymbolNew.h"
#include "ICopyStrategyReporter.h"
#include "NdbUpgrade.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;


namespace
{
    const SectionViewSymbolNew* GetSectionViewSymbolByOwnerElement(const IElement* pSectionViewSymbolOwnerElement)
    {
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pSectionViewSymbolOwnerElement != nullptr, L"Invalid pOwnerElement",L"GDMPLab",L"2024-03-30");

        const IGenericElement* pGenericElement = quick_cast<IGenericElement>(pSectionViewSymbolOwnerElement);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pGenericElement != nullptr, L"Invalid pGenericElement",L"GDMPLab",L"2024-03-30");

         return (quick_cast<SectionViewSymbolNew>(pGenericElement->GetExternalObject()));
    }

    SectionViewSymbolNew* GetSectionViewSymbolByOwnerElementFW(IElement* pSectionViewSymbolOwnerElement)
    {
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pSectionViewSymbolOwnerElement != nullptr, L"Invalid pOwnerElement",L"GDMPLab",L"2024-03-30");

        IGenericElement* pGenericElement = quick_cast<IGenericElement>(pSectionViewSymbolOwnerElement);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pGenericElement != nullptr, L"Invalid pGenericElement",L"GDMPLab",L"2024-03-30");

        return (quick_cast<SectionViewSymbolNew>(pGenericElement->GetExternalObject()));
    }

    IModelView* GetSectionModelViewBySectionViewSymbolOwnerElement(const IElement* pSectionViewSymbolOwnerElement)
    {
        const SectionViewSymbolNew *pSectionViewSymbol = GetSectionViewSymbolByOwnerElement(pSectionViewSymbolOwnerElement);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pSectionViewSymbol != nullptr, L"Invalid pSectionViewSymbol",L"GDMPLab",L"2024-03-30");

        return pSectionViewSymbol->GetSectionModelView();
    }
}

namespace gcmp
{
    // 剖面标志夹点位置更新计算器
    class SectionViewSymbolNewGripPointPositionCalculator : public GbmpCalculatorBase
    {
        DECLARE_CALCULATOR(SectionViewSymbolNewGripPointPositionCalculator, IElementShapeHandle)
    public:
        SectionViewSymbolNewGripPointPositionCalculator(IDocument* pDoc, const RegenDataId& outputDataId) : GbmpCalculatorBase(pDoc, outputDataId) {}
        virtual void ReportInputDataIds(std::vector<RegenDataId> & dataIds) const override;
        virtual void Execute() override;
    };

    // 剖面标志辅助线位置更新计算器
    class SectionViewSymbolNewBorderCalculator : public gcmp::GbmpCalculatorBase
    {
        DECLARE_CALCULATOR(SectionViewSymbolNewBorderCalculator, IElementShapeHandle)
    public:
        SectionViewSymbolNewBorderCalculator(IDocument* pDoc, const RegenDataId& outputDataId) : GbmpCalculatorBase(pDoc, outputDataId) {}
        virtual void ReportInputDataIds(std::vector<RegenDataId> & dataIds) const override;
        virtual void Execute() override;
    };

    // 剖面视图标记更新计算器
    class SectionViewSymbolNewRegenerationCalculator : public GbmpCalculatorBase
    {
        DECLARE_CALCULATOR(SectionViewSymbolNewRegenerationCalculator, IElement)
    public:
        SectionViewSymbolNewRegenerationCalculator(IDocument* pDoc, const RegenDataId& outputDataId) : GbmpCalculatorBase(pDoc, outputDataId) {}
        virtual void ReportInputDataIds(std::vector<RegenDataId> & dataIds) const override;
        virtual void Execute() override;
    };
}

#pragma region BorderCalculator
IMPLEMENT_CALCULATOR_CREATOR(gcmp, SectionViewSymbolNewBorderCalculator);

void SectionViewSymbolNewBorderCalculator::ReportInputDataIds(std::vector<RegenDataId> & dataIds) const
{
    IElementShapeHandle* pElementShapeHandle = GetElement<IElementShapeHandle>();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShapeHandle, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");

    dataIds.push_back(pElementShapeHandle->GetMasterIdRdIdForBehavior());
    dataIds.push_back(pElementShapeHandle->GetShapeHandlePositionIndexInMasterElementRdId());

    IDocument * pDoc = pElementShapeHandle->GetDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"invalid pDoc",L"GDMPLab",L"2024-03-30");
    IElement* pMasterElem = pDoc->GetElement(pElementShapeHandle->GetMasterId());
    DBG_WARN_AND_RETURN_VOID_UNLESS(pMasterElem, L"invalid pMasterElement",L"GDMPLab",L"2024-03-30");

    const SectionViewSymbolNew *pSymbol = GetSectionViewSymbolByOwnerElement(pMasterElem);
    dataIds.push_back(pSymbol->GetModelViewRangeUpdatedRdId());
}

void SectionViewSymbolNewBorderCalculator::Execute()
{
    IElementShapeHandle* pElementShapeHandle = GetElement<IElementShapeHandle>();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShapeHandle, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");

    IDocument *pDoc = this->GetDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"invalid pDoc",L"GDMPLab",L"2024-03-30");
    IElement* pElement = pDoc->GetElement(pElementShapeHandle->GetMasterId());
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElement, L"invalid pElement",L"GDMPLab",L"2024-03-30");
    // The host may have been deleted via undo/redo
    if (nullptr == pElement)
    {
        return;
    }

    IElementShapeHandleBehavior* pElementShapeHandleBehavior = pElementShapeHandle->GetElementShapeHandleBehavior();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShapeHandleBehavior, L"invalid pElementShapeHandleBehavior为空",L"GDMPLab",L"2024-03-30");
    pElementShapeHandleBehavior->UpdatePosition();
}
#pragma endregion BorderCalculator

#pragma region BorderBehavior
DBOBJECT_DATA_DEFINE(SectionViewSymbolNewBorderBehavior)
{
    m_Document = nullptr;
}

SectionViewSymbolNewBorderBehavior::SectionViewSymbolNewBorderBehavior(IDocument* pDoc, const ElementId& modelViewId)
    :m_Document(pDoc), m_ModelViewId(modelViewId)
{

}

IElementShapeHandle* SectionViewSymbolNewBorderBehavior::GetElementShapeHandle() const
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(m_Document, L"invalid pDocument",L"GDMPLab",L"2024-03-30");
    return quick_cast<IElementShapeHandle>(m_Document->GetElement(m_ElementShapeHandleId));
}

IElement * SectionViewSymbolNewBorderBehavior::GetMasterElement() const
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(m_Document, L"invalid pDocument",L"GDMPLab",L"2024-03-30");

    IElementShapeHandle *pElementShapeHandle = GetElementShapeHandle();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pElementShapeHandle, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");

    return m_Document->GetElement(pElementShapeHandle->GetMasterId());
}

OwnerPtr<IElementShapeHandleBehavior> SectionViewSymbolNewBorderBehavior::Create(IDocument* pDoc, const ElementId& modelViewId)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDoc && modelViewId.IsValid(), L"invalid parameter",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(SectionViewSymbolNewBorderBehavior, pDoc, modelViewId);
}

void SectionViewSymbolNewBorderBehavior::GetCalculators(ICalculatorCollection* calculators) const
{
    IElementShapeHandle* pElementShapeHandle = GetElementShapeHandle();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShapeHandle != nullptr, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");

    ADD_CALCULATOR(SectionViewSymbolNewBorderCalculator, pElementShapeHandle->GetDocument(), pElementShapeHandle->GetPositionRdIdForBehavior());
}

bool SectionViewSymbolNewBorderBehavior::Translate(const IElementMoveContext & moveContext)
{
    return true;
}

OwnerPtr<IGraphicsElementShape> SectionViewSymbolNewBorderBehavior::CreateGrahicsElementShapeInModelView(const IModelView* pModelView) const
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModelView != nullptr, L"invalid pModelView",L"GDMPLab",L"2024-03-30");

    if (!GetModelViewId().HasSameValue(pModelView->GetElementId()))
        return nullptr;

    //获取剖面视图视点、视图方向、视图右方向、视图上方向、视口、底部偏移
    IElement *pMasterElement = GetMasterElement();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pMasterElement != nullptr, L"invalid pMasterElement",L"GDMPLab",L"2024-03-30");
    IModelView *pSectionModelView = GetSectionModelViewBySectionViewSymbolOwnerElement(pMasterElement);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pSectionModelView, L"invalid pSectionModelView",L"GDMPLab",L"2024-03-30");
    IViewClipRange* pViewClipRange = IViewClipRange::GetViewClipRange(pSectionModelView->GetDocument(), pSectionModelView->GetViewClipRangeId());
    Vector3d sectionViewPoint = pSectionModelView->GetOrigin();
    Vector3d sectionViewRightDir = pSectionModelView->GetRightDirection();
    Vector3d sectionViewUpDir = pSectionModelView->GetUpDirection();
    Vector3d sectionViewDir = pSectionModelView->GetViewDirection();
    sectionViewRightDir.Normalize();
    sectionViewUpDir.Normalize();
    sectionViewDir.Normalize();
    double viewPortLeftOffset = 0;
    double viewPortRightOffset = 0;
    double viewPortUpOffset = 0;
    double viewPortDownOffset = 0;
    double viewBottomOffset = 0;
    {
        bool bOk = pViewClipRange->GetRectViewClipRange(viewPortLeftOffset, viewPortRightOffset, viewPortUpOffset, viewPortDownOffset);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(bOk, L"Fail to get DefaultRectViewport",L"GDMPLab",L"2024-03-30");
        bOk = pSectionModelView->GetBottomPlaneOffset(viewBottomOffset);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(bOk, L"Fail to get BottomOffset",L"GDMPLab",L"2024-03-30");
    }

    //获取辅助线类型
    IElementShapeHandle *pElementShapeHandle = GetElementShapeHandle();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pElementShapeHandle != nullptr, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");
    int positionIndex = pElementShapeHandle->GetPositionIndexInMasterElement();
    SectionViewSymbolNewAuxiliaryType borderType = (SectionViewSymbolNewAuxiliaryType)positionIndex;

    Vector3d point_1;
    Vector3d point_2;
    switch (borderType)
    {
    case SectionViewSymbolNewAuxiliaryType::BoxUpPlaneLeftBorderType:
    {
        point_1 = sectionViewPoint + (-sectionViewRightDir)*viewPortLeftOffset + sectionViewUpDir*viewPortUpOffset;
        point_2 = point_1 + sectionViewDir*viewBottomOffset;
        break;
    }
    case SectionViewSymbolNewAuxiliaryType::BoxUpPlaneRightBorderType:
    {
        point_1 = sectionViewPoint + sectionViewRightDir*viewPortRightOffset + sectionViewUpDir*viewPortUpOffset;
        point_2 = point_1 + sectionViewDir*viewBottomOffset;
        break;
    }
    case SectionViewSymbolNewAuxiliaryType::BoxUpPlaneFrontBorderType:
    {
        point_1 = sectionViewPoint + (-sectionViewRightDir)*viewPortLeftOffset + sectionViewUpDir*viewPortUpOffset;
        point_2 = sectionViewPoint + sectionViewRightDir*viewPortRightOffset + sectionViewUpDir*viewPortUpOffset;
        break;
    }
    case SectionViewSymbolNewAuxiliaryType::BoxUpPlaneBackBorderType:
    {
        point_1 = sectionViewPoint + (-sectionViewRightDir)*viewPortLeftOffset + sectionViewUpDir*viewPortUpOffset + sectionViewDir*viewBottomOffset;
        point_2 = sectionViewPoint + sectionViewRightDir*viewPortRightOffset + sectionViewUpDir*viewPortUpOffset + sectionViewDir*viewBottomOffset;
        break;
    }
    case SectionViewSymbolNewAuxiliaryType::BoxRightPlaneFrontBorderType:
    {
        point_1 = sectionViewPoint + sectionViewRightDir*viewPortRightOffset + sectionViewUpDir*viewPortUpOffset;
        point_2 = sectionViewPoint + sectionViewRightDir*viewPortRightOffset + (-sectionViewUpDir)*viewPortDownOffset;
        break;
    }
    case SectionViewSymbolNewAuxiliaryType::BoxRightPlaneBackBorderType:
    {
        point_1 = sectionViewPoint + sectionViewRightDir*viewPortRightOffset + sectionViewUpDir*viewPortUpOffset + sectionViewDir*viewBottomOffset;
        point_2 = sectionViewPoint + sectionViewRightDir*viewPortRightOffset + (-sectionViewUpDir)*viewPortDownOffset + sectionViewDir*viewBottomOffset;
        break;
    }
    case SectionViewSymbolNewAuxiliaryType::BoxRightPlaneBottomBorderType:
    {
        point_1 = sectionViewPoint + sectionViewRightDir*viewPortRightOffset + (-sectionViewUpDir)*viewPortDownOffset;
        point_2 = sectionViewPoint + sectionViewRightDir*viewPortRightOffset + (-sectionViewUpDir)*viewPortDownOffset + sectionViewDir*viewBottomOffset;
        break;
    }
    default:
        break;
    }

    //构造临时工作平面
    OwnerPtr<IPlane> opTmpWorkPlane = IPlane::Create(pModelView->GetOrigin(), pModelView->GetViewDirection());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opTmpWorkPlane != nullptr, L"invalid opTmpWorkPlane",L"GDMPLab",L"2024-03-30");
    Vector2d uvParameter;
    AlgorithmProject::Project(point_1, opTmpWorkPlane.get(), uvParameter, point_1);
    AlgorithmProject::Project(point_2, opTmpWorkPlane.get(), uvParameter, point_2);

    //创建辅助线并设置样式
    OwnerPtr<IGraphicsLine> opLine = IGraphicsLine::Create(point_1, point_2);
    IGraphicsStyleManager* pStyleManager = GetDocument()->GetGraphicsStyleManager();
    if (pStyleManager)
    {
        opLine->SetGraphicsStyleId(pStyleManager->GetGraphicsStyleIdByCategoryUid(BuiltInCategoryUniIdentities::BICU_VIEW_SYMBOL_AUXILIARY_BORDER));
    }

    OwnerPtr<IGraphicsElementShape> opGGrepNodeRoot = IGraphicsElementShape::Create(GraphicsRenderLayer::TransientObject);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGGrepNodeRoot != nullptr, L"invalid opGGrepNodeRoot",L"GDMPLab",L"2024-03-30");
    opGGrepNodeRoot->AddChild(TransferOwnership(opLine));

    opGGrepNodeRoot->SetElementId(pElementShapeHandle->GetElementId());
    opGGrepNodeRoot->SetIsClippable(false);

    return opGGrepNodeRoot;
}

void SectionViewSymbolNewBorderBehavior::ReportParents(IElementParentReporter& reporter) const
{
    reporter.ReportWeak(GetModelViewId());
}

void SectionViewSymbolNewBorderBehavior::UpdatePosition()
{
    IElementShapeHandle* pElementShapeHandle = GetElementShapeHandle();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShapeHandle != nullptr, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");

    const IElement* pOwnerElement = GetMasterElement();

    //注：这里必须调用const版本的pOwnerElement，否则会引起事务外修改Element的DBG_WARN
    const IElementPositionPoints* pPositionPoints = pOwnerElement->GetPositionPoints();
    if (pPositionPoints)
    {
        int positionIndex = pElementShapeHandle->GetPositionIndexInMasterElement();
        Vector3d pos = pPositionPoints->GetControlPoint(positionIndex);
        pElementShapeHandle->SetPosition(pos);
    }
}

void SectionViewSymbolNewBorderBehavior::GetNearestPoint(Vector3d& nearPoint) const
{
    IElementShapeHandle* pElementShapeHandle = GetElementShapeHandle();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShapeHandle != nullptr, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");
    nearPoint = pElementShapeHandle->GetPosition();
}

bool SectionViewSymbolNewBorderBehavior::GetHandleCommandString(const IObject* commandEnvironment, std::wstring& commandStr, CommandParameters& cmdParams) const\
{
    return false;
}
#pragma endregion BorderBehavior

#pragma region GripPointPositionCalculator
IMPLEMENT_CALCULATOR_CREATOR(gcmp, SectionViewSymbolNewGripPointPositionCalculator);

void SectionViewSymbolNewGripPointPositionCalculator::ReportInputDataIds(std::vector<RegenDataId> & dataIds) const
{
    IElementShapeHandle* pElementShapeHandle = GetElement<IElementShapeHandle>();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShapeHandle, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");

    dataIds.push_back(pElementShapeHandle->GetMasterIdRdIdForBehavior());
    dataIds.push_back(pElementShapeHandle->GetShapeHandlePositionIndexInMasterElementRdId());

    IDocument * pDoc = pElementShapeHandle->GetDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"invalid pDoc",L"GDMPLab",L"2024-03-30");
    IElement* pMasterElem = pDoc->GetElement(pElementShapeHandle->GetMasterId());
    DBG_WARN_AND_RETURN_VOID_UNLESS(pMasterElem, L"invalid pMasterElement",L"GDMPLab",L"2024-03-30");
    const IElementModelShape *pElementShape = pMasterElem->GetElementModelShape();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShape, L"invalid pElementShape",L"GDMPLab",L"2024-03-30");
    dataIds.push_back(pElementShape->GetGraphicsElementShapeRdId());

    const SectionViewSymbolNew *pSymbol = GetSectionViewSymbolByOwnerElement(pMasterElem);
    dataIds.push_back(pSymbol->GetModelViewRangeUpdatedRdId());
}

void SectionViewSymbolNewGripPointPositionCalculator::Execute()
{
    IElementShapeHandle* pElementShapeHandle = GetElement<IElementShapeHandle>();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShapeHandle, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");

    IDocument *pDoc = this->GetDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"invalid pDoc",L"GDMPLab",L"2024-03-30");

    IElement* pElement = pDoc->GetElement(pElementShapeHandle->GetMasterId());
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElement, L"invalid pElement",L"GDMPLab",L"2024-03-30");
    // The host may have been deleted via undo/redo
    if (nullptr == pElement)
    {
        return;
    }

    IElementShapeHandleBehavior* pElementShapeHandleBehavior = pElementShapeHandle->GetElementShapeHandleBehavior();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShapeHandleBehavior, L"invalid pElementShapeHandleBehavior为空",L"GDMPLab",L"2024-03-30");
    pElementShapeHandleBehavior->UpdatePosition();
}

#pragma endregion GripPointPositionCalculator

#pragma region GripPointBehavior
DBOBJECT_DATA_DEFINE(SectionViewSymbolNewGripPointBehavior)
{
    m_Document = nullptr;
}

SectionViewSymbolNewGripPointBehavior::SectionViewSymbolNewGripPointBehavior(IDocument* pDoc, const ElementId& modelViewId)
    :m_Document(pDoc), m_ModelViewId(modelViewId)
{

}

IElementShapeHandle* SectionViewSymbolNewGripPointBehavior::GetElementShapeHandle() const
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(m_Document, L"invalid pDocument",L"GDMPLab",L"2024-03-30");
    return quick_cast<IElementShapeHandle>(m_Document->GetElement(m_ElementShapeHandleId));
}

IElement * SectionViewSymbolNewGripPointBehavior::GetMasterElement() const
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(m_Document, L"invalid pDocument",L"GDMPLab",L"2024-03-30");

    IElementShapeHandle *pElementShapeHandle = GetElementShapeHandle();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pElementShapeHandle, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");

    return m_Document->GetElement(pElementShapeHandle->GetMasterId());
}

OwnerPtr<IElementShapeHandleBehavior> SectionViewSymbolNewGripPointBehavior::Create(IDocument* pDoc, const ElementId& modelViewId)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDoc && modelViewId.IsValid(), L"invalid parameter",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(SectionViewSymbolNewGripPointBehavior, pDoc, modelViewId);
}

void SectionViewSymbolNewGripPointBehavior::GetCalculators(ICalculatorCollection* calculators) const
{
    IElementShapeHandle* pElementShapeHandle = GetElementShapeHandle();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShapeHandle != nullptr, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");

    ADD_CALCULATOR(SectionViewSymbolNewGripPointPositionCalculator, pElementShapeHandle->GetDocument(), pElementShapeHandle->GetPositionRdIdForBehavior());
}

bool SectionViewSymbolNewGripPointBehavior::Translate(const IElementMoveContext & moveContext)
{
    IElementShapeHandle* pElementShapeHandle = GetElementShapeHandle();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pElementShapeHandle != nullptr, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");

    IElement *pOwnerElement = GetMasterElement();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pOwnerElement, L"invalid pOwnerElement",L"GDMPLab",L"2024-03-30");

    IElementPositionPoints *pOwnerElementPosPoint = pOwnerElement->GetPositionPoints();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pOwnerElementPosPoint, L"invalid pOwnerElementPosPoint",L"GDMPLab",L"2024-03-30");

    int positionIndex = pElementShapeHandle->GetPositionIndexInMasterElement();

    Vector3d pos = pOwnerElementPosPoint->GetControlPoint(positionIndex);
    pOwnerElementPosPoint->SetControlPoint(positionIndex, pos + moveContext.GetMoveVector());

    //触发所有辅助对象关联更新
    std::vector<ElementId> vecGripPointIds = AuxiliaryElementUtils::GetAuxiliaryElements(pOwnerElement);
    return pOwnerElement->GetDocument()->GetRegenerator()->ForceRegeneratingElements(vecGripPointIds);
}

OwnerPtr<IGraphicsElementShape> SectionViewSymbolNewGripPointBehavior::CreateGrahicsElementShapeInModelView(const IModelView* pModelView) const
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModelView != nullptr, L"invalid pModelView",L"GDMPLab",L"2024-03-30");

    if (!GetModelViewId().HasSameValue(pModelView->GetElementId()))
        return nullptr;

    IElementShapeHandle* pElementShapeHandle = GetElementShapeHandle();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pElementShapeHandle != nullptr, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");

    Vector3d workPlaneOrigin = pModelView->GetOrigin();
    Vector3d workPlaneViewDir = pModelView->GetViewDirection();
    OwnerPtr<IPlane> opWorkPlane = IPlane::Create(workPlaneOrigin, workPlaneViewDir);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opWorkPlane != nullptr, L"invalid opWorkPlane",L"GDMPLab",L"2024-03-30");

    // 更新GRep
    OwnerPtr<IGraphicsElementShape> opGGrepNodeRoot = IGraphicsElementShape::Create(GraphicsRenderLayer::TransientObject);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGGrepNodeRoot != nullptr, L"invalid opGGrepNodeRoot",L"GDMPLab",L"2024-03-30");

    Vector3d position;
    Vector2d uvParameter;
    AlgorithmProject::Project(pElementShapeHandle->GetPosition(), opWorkPlane.get(), uvParameter, position);

    OwnerPtr<IGraphicsPoint> opPoint = IGraphicsPoint::Create(position);
    opPoint->SetDisplayShape(PointDisplayShapeType::Circle);
    opGGrepNodeRoot->AddChild(TransferOwnership(opPoint));
    opGGrepNodeRoot->SetElementId(pElementShapeHandle->GetElementId());
    opGGrepNodeRoot->SetIsClippable(false);

    // 设置属性
    IGraphicsStyleManager* pStyleManager = GetDocument()->GetGraphicsStyleManager();
    if (pStyleManager)
    {
        ElementId gstyleId = pStyleManager->GetGraphicsStyleIdByCategoryUid(BuiltInCategoryUniIdentities::BICU_AUXILIARY_ELEMENT);
        opGGrepNodeRoot->SetGraphicsStyleId(gstyleId);
    }

    return opGGrepNodeRoot;
}

void SectionViewSymbolNewGripPointBehavior::ReportParents(IElementParentReporter& reporter) const
{
    reporter.ReportWeak(GetModelViewId());
}

void SectionViewSymbolNewGripPointBehavior::UpdatePosition()
{
    IElementShapeHandle* pElementShapeHandle = GetElementShapeHandle();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShapeHandle != nullptr, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");

    const IElement* pOwnerElement = GetMasterElement();

    //注：这里必须调用const版本的pOwnerElement，否则会引起事务外修改Element的DBG_WARN
    const IElementPositionPoints* pPositionPoints = pOwnerElement->GetPositionPoints();
    if (pPositionPoints)
    {
        int positionIndex = pElementShapeHandle->GetPositionIndexInMasterElement();
        Vector3d pos = pPositionPoints->GetControlPoint(positionIndex);
        pElementShapeHandle->SetPosition(pos);
    }
}

void SectionViewSymbolNewGripPointBehavior::GetNearestPoint(Vector3d& nearPoint) const
{
    IElementShapeHandle* pElementShapeHandle = GetElementShapeHandle();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElementShapeHandle != nullptr, L"invalid pElementShapeHandle",L"GDMPLab",L"2024-03-30");
    nearPoint = pElementShapeHandle->GetPosition();
}

bool SectionViewSymbolNewGripPointBehavior::GetHandleCommandString(const IObject* commandEnvironment, std::wstring& commandStr, CommandParameters& cmdParams) const\
{
    return false;
}
#pragma endregion GripPointBehavior

#pragma region ViewSpecificShapeBehavior

BEGIN_UPGRADE_CLASS(gcmp, SectionViewSymbolNewViewSpecificShapeComponent, 2)
ADD_OWNERPTR_IDB_PROPERTY(OwnerPtr<IRenderPriorityOffsetProvider>, RenderPriorityOffsetProvider)
END_UPGRADE_CLASS

BEGIN_UPGRADE_CLASS(gcmp, SectionViewSymbolNewViewSpecificShapeComponent, 3)
ADD_OWNERPTR_IDB_PROPERTY(OwnerPtr<IGraphicsNodeVisibilityCustomizer>, GraphicsNodeVisibilityCustomizer)
END_UPGRADE_CLASS

DBOBJECT_DATA_DEFINE(SectionViewSymbolNewViewSpecificShapeComponent)
{
    m_pOwnerElement = nullptr;
    m_GraphicsNodeVisibilityCustomizer = nullptr;
}

bool SectionViewSymbolNewViewSpecificShapeComponent::SetOwnerElement(IElement* pOwnerElement)
{
    m_pOwnerElement = pOwnerElement;
    IGraphicsNodeVisibilityCustomizer* pCustomizer = m_GraphicsNodeVisibilityCustomizer.get();
    if (pCustomizer)
    {
        pCustomizer->SetOwnerElement(pOwnerElement);
    }
    return true;
}

bool SectionViewSymbolNewViewSpecificShapeComponent::IsVisibleInModelView(const IModelView* pModelView) const
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView != nullptr, L"Invalid pModelView",L"GDMPLab",L"2024-03-30");

    const IModelView* pSectionView = GetSectionModelViewBySectionViewSymbolOwnerElement(GetOwnerElement());
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pSectionView != nullptr, L"Invalid pSectionView",L"GDMPLab",L"2024-03-30");

    Vector3d modelViewDir = pModelView->GetViewDirection();
    Vector3d sectionViewDir = pSectionView->GetViewDirection();
    Vector3d sectionViewUpDir = pSectionView->GetUpDirection();

    if (GbmpModelViewUtil::IsModelViewPlaneParallelToSectionBoxUpDownPlane(modelViewDir, sectionViewDir, sectionViewUpDir) ||
        GbmpModelViewUtil::IsModelViewPlaneParallelToSectionBoxLeftRightPlane(modelViewDir, sectionViewDir, sectionViewUpDir))
    {
        return true;
    }

    return false;
}

OwnerPtr<IGraphicsElementShape> SectionViewSymbolNewViewSpecificShapeComponent::CreateViewSpecificElementShape(const IModelView* pModelView) const
{
    const SectionViewSymbolNew *pSectionViewSymbol = GetSectionViewSymbolByOwnerElement(GetOwnerElement());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pSectionViewSymbol != nullptr, L"Invalid pSectionViewSymbol",L"GDMPLab",L"2024-03-30");

    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModelView != nullptr, L"Invalid pModelView",L"GDMPLab",L"2024-03-30");
    return pSectionViewSymbol->CreateModelViewElementShape(pModelView);
}

void SectionViewSymbolNewViewSpecificShapeComponent::ReportDependentElements(std::vector<ElementId>& dependentElementIds) const
{
    const IElement*pElement = GetOwnerElement();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pElement != nullptr, L"pElement is null",L"GDMPLab",L"2024-03-30");
    dependentElementIds.push_back(pElement->GetElementId());
}

void SectionViewSymbolNewViewSpecificShapeComponent::SetRenderPriorityOffsetProvider(OwnerPtr<IRenderPriorityOffsetProvider> opProvider)
{
    SetRenderPriorityOffsetProvider__(TransferOwnership(opProvider));
}

const IRenderPriorityOffsetProvider* SectionViewSymbolNewViewSpecificShapeComponent::GetRenderPriorityOffsetProvider() const
{
    return GetRenderPriorityOffsetProvider__().get();
}

IRenderPriorityOffsetProvider* SectionViewSymbolNewViewSpecificShapeComponent::GetRenderPriorityOffsetProvider()
{
    return GetRenderPriorityOffsetProviderFW__().get();
}

void SectionViewSymbolNewViewSpecificShapeComponent::SetGraphicsNodeVisibilityCustomizer(OwnerPtr<IGraphicsNodeVisibilityCustomizer> opCustomizer)
{
    if (opCustomizer)
    {
        opCustomizer->SetOwnerElement(GetOwnerElement());
    }
    SetGraphicsNodeVisibilityCustomizer__(TransferOwnership(opCustomizer));
}

const IGraphicsNodeVisibilityCustomizer* SectionViewSymbolNewViewSpecificShapeComponent::GetGraphicsNodeVisibilityCustomizer() const
{
    return GetGraphicsNodeVisibilityCustomizer__().get();
}

IGraphicsNodeVisibilityCustomizer* SectionViewSymbolNewViewSpecificShapeComponent::GetGraphicsNodeVisibilityCustomizer()
{
    return GetGraphicsNodeVisibilityCustomizerFW__().get();
}

#pragma endregion ViewSpecificShapeBehavior

#pragma region UiManipulatorComponent

DBOBJECT_DATA_DEFINE(SectionViewSymbolNewUiManipulatorComponent)
{
    m_pOwnerElement = nullptr;
}

ElementId SectionViewSymbolNewUiManipulatorComponent::CreateGripPoint(SectionViewSymbolNewAuxiliaryType type, const ElementId& modelviewId) const
{
    const IGenericElement* pGenericElement = quick_cast<IGenericElement>(m_pOwnerElement);
    DBG_WARN_AND_RETURN_UNLESS(pGenericElement != nullptr, ElementId::InvalidID, L"invalid pGenericElement",L"GDMPLab",L"2024-03-30");

    const IElementPositionPoints* pOwnerPositionPoints = pGenericElement->GetPositionPoints();
    Vector3d pos = pOwnerPositionPoints ? pOwnerPositionPoints->GetControlPoint((int)type) : Vector3d::Zero;

    OwnerPtr<IElementShapeHandleBehavior> pGripPointBehavior = SectionViewSymbolNewGripPointBehavior::Create(m_pOwnerElement->GetDocument(), modelviewId);

    IElementShapeHandle* pGripPoint = IElementShapeHandle::Create(
        TransferOwnership(pGripPointBehavior),
        pGenericElement->GetElementId(),
        pos, static_cast<int>(type));
    DBG_WARN_AND_RETURN_UNLESS(pGripPoint != nullptr, ElementId::InvalidID, L"invalid pGripPoint",L"GDMPLab",L"2024-03-30");

    return pGripPoint->GetElementId();
}

ElementId SectionViewSymbolNewUiManipulatorComponent::CreateBorder(SectionViewSymbolNewAuxiliaryType type, const gcmp::ElementId& modelviewId) const
{
    const IGenericElement* pGenericElement = quick_cast<IGenericElement>(m_pOwnerElement);
    DBG_WARN_AND_RETURN_UNLESS(pGenericElement != nullptr, ElementId::InvalidID, L"invalid pGenericElement",L"GDMPLab",L"2024-03-30");

    const IElementPositionPoints* pOwnerPositionPoints = pGenericElement->GetPositionPoints();
    //borderPos并不是必需数据，只是调用IElementShapeHandle::Create（）设置进去的
    Vector3d borderPos;
    OwnerPtr<IElementShapeHandleBehavior> pBorderBehavior = SectionViewSymbolNewBorderBehavior::Create(m_pOwnerElement->GetDocument(), modelviewId);

    IElementShapeHandle* pBorder = IElementShapeHandle::Create(
        TransferOwnership(pBorderBehavior),
        pGenericElement->GetElementId(),
        borderPos, static_cast<int>(type));
    DBG_WARN_AND_RETURN_UNLESS(pBorder != nullptr, ElementId::InvalidID, L"invalid pBorder",L"GDMPLab",L"2024-03-30");

    return pBorder->GetElementId();
}

#pragma endregion UiManipulatorComponent

#pragma region TransformationComponent

DBOBJECT_DATA_DEFINE(SectionViewSymbolNewTransformationComponent)
{
    m_pOwnerElement = nullptr;
}

bool SectionViewSymbolNewTransformationComponent::CanBeMoved(std::wstring*) const
{
    const IElement* pElement = GetOwnerElement();
    if (pElement == nullptr)
        return true;

    return pElement->GetStatus()->CanBeMoved();
}

bool SectionViewSymbolNewTransformationComponent::Translate(const IElementMoveContext& moveContext)
{
    Vector3d moveDir = moveContext.GetMoveVector();
    Matrix4d translationMat;
    translationMat.MakeTranslate(moveDir.X(), moveDir.Y(), moveDir.Z());
    return this->Transform(translationMat);
}

bool SectionViewSymbolNewTransformationComponent::CanBeRotated(std::wstring* explanation /*= nullptr*/) const
{
    const IElement* pElement = GetOwnerElement();
    if (pElement == nullptr)
        return true;

    const IElementStatus* pStatus = pElement->GetStatus();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pStatus, L"pStatus 不能为空!",L"GDMPLab",L"2024-03-30");
    return pStatus->CanBeRotated();
}

bool gcmp::SectionViewSymbolNewTransformationComponent::Rotate(const Vector3d& pointOnVec, const Vector3d& rotateDir, double rotateAngle)
{
    Matrix4d rotateMat;
    rotateMat.MakeRotate(pointOnVec, rotateDir, rotateAngle);
    return this->Transform(rotateMat);
}


bool SectionViewSymbolNewTransformationComponent::Transform(const Matrix4d& matrix)
{
    IElement *pOwnerElement = GetOwnerElement();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pOwnerElement, L"Invalid pOwnerElement",L"GDMPLab",L"2024-03-30");

    SectionViewSymbolNew* pSectionViewSymbol = GetSectionViewSymbolByOwnerElementFW(pOwnerElement);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pSectionViewSymbol, L"invalid pSectionViewSymbol",L"GDMPLab",L"2024-03-30");

    pSectionViewSymbol->MakeTransform(matrix);

    //触发所有辅助对象关联更新
    std::vector<ElementId> vecGripPointIds = AuxiliaryElementUtils::GetAuxiliaryElements(pOwnerElement);
    pOwnerElement->GetDocument()->GetRegenerator()->ForceRegeneratingElements(vecGripPointIds);

    return true;
}
#pragma endregion TransformationComponent

#pragma region ParametersCustomizer
DBOBJECT_DATA_DEFINE(SectionViewSymbolNewParametersCustomizer)
{
    SetOwnerElement(nullptr);
}

OwnerPtr<IParameter> SectionViewSymbolNewParametersCustomizer::GetNativeParameter(int paramDefId) const
{
    const IElementParameters* pElementParameters = GetSectionModelViewParameters();
    if (!pElementParameters) {
        return nullptr;
    }

    return pElementParameters->GetNativeParameter(paramDefId);
}

bool SectionViewSymbolNewParametersCustomizer::SetNativeParameter(const IParameter *param, std::wstring* errorMsg)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(param, L"param is null.",L"GDMPLab",L"2024-03-30");

    IElementParameters* pElementParameters = GetSectionModelViewParameters();
    if (!pElementParameters)
        return false;
    return pElementParameters->SetNativeParameter(param, errorMsg);
}

void SectionViewSymbolNewParametersCustomizer::ReportParameterDefinitions(std::vector<int>* pParamDefIds) const
{
    const IElementParameters* pElementParameters = GetSectionModelViewParameters();
    if (!pElementParameters)
        return;
    return pElementParameters->ReportParameterDefinitions(pParamDefIds);
}

bool SectionViewSymbolNewParametersCustomizer::IsParameterModifiable(int parameterId) const
{
    const IElementParameters* pElementParameters = GetSectionModelViewParameters();
    if (!pElementParameters)
        return false;
    return pElementParameters->IsParameterModifiable(parameterId);
}

const IElementParameters* SectionViewSymbolNewParametersCustomizer::GetSectionModelViewParameters() const
{
    IModelView* pSectionModelView = GetSectionModelViewBySectionViewSymbolOwnerElement(GetOwnerElement());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pSectionModelView, L"Invalid pSectionModelView",L"GDMPLab",L"2024-03-30");

    return pSectionModelView->GetElementParameters();
}

IElementParameters* SectionViewSymbolNewParametersCustomizer::GetSectionModelViewParameters()
{
    IModelView* pSectionModelView = GetSectionModelViewBySectionViewSymbolOwnerElement(GetOwnerElement());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pSectionModelView, L"Invalid pSectionModelView",L"GDMPLab",L"2024-03-30");

    return pSectionModelView->GetElementParameters();
}

#pragma endregion ParametersCustomizer

#pragma region NameParameterOverride

DBOBJECT_DATA_DEFINE(SectionViewSymbolNewNameParameterOverride)
{
    m_pOwnerElement = nullptr;
}

DEFINE_MODEL_VIEW_SYMBOL_NEW_PARAMETER_OVERRID_METHODS(SectionViewSymbolNewNameParameterOverride);

const UniIdentity& SectionViewSymbolNewNameParameterOverride::GetUidForParameterOverride() const
{
    return PARAMETER_UID(ElementNameBuiltInParameter);
}

#pragma endregion NameParameterOverride

#pragma region TopPlaneOffsetParameterOverride

DBOBJECT_DATA_DEFINE(SectionViewSymbolNewTopPlaneOffsetParameterOverride)
{
    m_pOwnerElement = nullptr;
}

DEFINE_MODEL_VIEW_SYMBOL_NEW_PARAMETER_OVERRID_METHODS(SectionViewSymbolNewTopPlaneOffsetParameterOverride);

const UniIdentity& SectionViewSymbolNewTopPlaneOffsetParameterOverride::GetUidForParameterOverride() const
{
    return PARAMETER_UID(ViewTopOffsetBuiltInParameter);
}

#pragma endregion TopPlaneOffsetParameterOverride

#pragma region RegenerationCalculator
IMPLEMENT_CALCULATOR_CREATOR(gcmp, SectionViewSymbolNewRegenerationCalculator);
void SectionViewSymbolNewRegenerationCalculator::ReportInputDataIds(std::vector<RegenDataId> & dataIds) const
{
    IGenericElement* pOwnerElement = GetElement<IGenericElement>();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pOwnerElement, L"invalid pOwnerElement",L"GDMPLab",L"2024-03-30");

    IModelView *pModelView = GetSectionModelViewBySectionViewSymbolOwnerElement(pOwnerElement);
    dataIds.push_back(pModelView->GetOriginRdId());
    dataIds.push_back(pModelView->GetViewDirectionRdId());
    dataIds.push_back(pModelView->GetRightDirectionRdId());
    dataIds.push_back(pModelView->GetUpDirectionRdId());
    dataIds.push_back(pModelView->GetRangeUpdatedRdId());
}

void SectionViewSymbolNewRegenerationCalculator::Execute()
{
    IGenericElement* pOwnerElement = GetElement<IGenericElement>();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pOwnerElement, L"invalid pOwnerElement",L"GDMPLab",L"2024-03-30");

    SectionViewSymbolNew* pSectionSymbol = GetSectionViewSymbolByOwnerElementFW(pOwnerElement);
    pSectionSymbol->MarkModelViewRangeUpdatedRdId();
}
#pragma endregion RegenerationCalculator

#pragma region RegenerationBehavior
DBOBJECT_DATA_DEFINE(SectionViewSymbolNewRegenerationBehavior)
{
    m_opOwnerElement = nullptr;
    m_ElementRegenerationBehavior = IElementRegenerationComponent::CreateDefaultRegenerationComponent();
}

SectionViewSymbolNewRegenerationBehavior::SectionViewSymbolNewRegenerationBehavior(IElement* pElement)
{
    m_opOwnerElement = pElement;
    m_ElementRegenerationBehavior = IElementRegenerationComponent::CreateDefaultRegenerationComponent();
}

bool SectionViewSymbolNewRegenerationBehavior::SetOwnerElement(IElement* pOwnerElement)
{
    m_opOwnerElement = pOwnerElement;
    if (m_ElementRegenerationBehavior.get())
        m_ElementRegenerationBehavior->SetOwnerElement(pOwnerElement);
    return true;
}

bool SectionViewSymbolNewRegenerationBehavior::CanHaveRegenData() const
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(m_ElementRegenerationBehavior, L"m_ElementRegenerationBehavior无效",L"GDMPLab",L"2024-03-30");
    return m_ElementRegenerationBehavior->CanHaveRegenData();
}

bool SectionViewSymbolNewRegenerationBehavior::CanHaveCalculators() const
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(m_ElementRegenerationBehavior, L"m_ElementRegenerationBehavior无效",L"GDMPLab",L"2024-03-30");
    return m_ElementRegenerationBehavior->CanHaveCalculators();
}

DECLARE_CALCULATOR_CREATOR(SectionViewSymbolNewRegenerationCalculator);
void SectionViewSymbolNewRegenerationBehavior::GetCalculators(ICalculatorCollection* calculators) const
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_ElementRegenerationBehavior, L"m_ElementRegenerationBehavior无效",L"GDMPLab",L"2024-03-30");
    m_ElementRegenerationBehavior->GetCalculators(calculators);

    const SectionViewSymbolNew *pSymbol = GetSectionViewSymbolByOwnerElement(m_opOwnerElement);
    RegenDataId modelViewUpdatedRengenId = pSymbol->GetModelViewRangeUpdatedRdId();

    ADD_CALCULATOR(SectionViewSymbolNewRegenerationCalculator, GetDocument(), modelViewUpdatedRengenId);
}

IDocument * SectionViewSymbolNewRegenerationBehavior::GetDocument() const
{
    if (!m_opOwnerElement)
    {
        return nullptr;
    }
    return m_opOwnerElement->GetDocument();
}

#pragma endregion RegenerationBehavior

#pragma region CopyStrategyComponent
DBOBJECT_DATA_DEFINE(SectionViewSymbolNewCopyStrategyComponent) 
{
    m_pOwnerElement = nullptr;
    m_CopyStrategyComponent = IElementCopyStrategyComponent::CreateReportCoreComponentsCopyStrategyComponent();
}

bool SectionViewSymbolNewCopyStrategyComponent::SetOwnerElement(IElement* pOwnerElement)
{
    m_pOwnerElement = pOwnerElement;
    m_CopyStrategyComponent->SetOwnerElement(pOwnerElement);
    return true;
}

void SectionViewSymbolNewCopyStrategyComponent::Report(const gcmp::ICopyContext & copyContext, gcmp::ICopyStrategyReporter& reporter) const
{
    if (!m_pOwnerElement)
        return;

    m_CopyStrategyComponent->Report(copyContext, reporter);

    if (const IGenericElement* pGenericEle = dynamic_cast<const IGenericElement*>(m_pOwnerElement))
    {
        const SectionViewSymbolNew* pSectionViewSymbolN = dynamic_cast<const SectionViewSymbolNew*>(pGenericEle->GetExternalObject());
        DBG_WARN_AND_RETURN_VOID_UNLESS(pSectionViewSymbolN, L"获取到的SectionViewSymbolNew指针不应该为空",L"GDMPLab",L"2024-03-30");
        if (pSectionViewSymbolN)
        {
            reporter.ReportToCopy(pSectionViewSymbolN->GetModelViewId());
        }
    }
}
#pragma endregion CopyStrategyComponent

#pragma region CopyPasteComponent
DBOBJECT_DATA_DEFINE(SectionViewSymbolNewCopyPasteComponent)
{
    m_pOwnerElement = nullptr;
    m_CopyPasteComponent = IElementCopyPasteComponent::CreateCopyWithExternalDataCopyPasteComponent();
}

SectionViewSymbolNewCopyPasteComponent::SectionViewSymbolNewCopyPasteComponent(IElement* pElement)
{
    m_pOwnerElement = pElement;
    m_CopyPasteComponent->SetOwnerElement(pElement);
}

bool SectionViewSymbolNewCopyPasteComponent::SetOwnerElement(IElement* pOwnerElement)
{
    m_pOwnerElement = pOwnerElement;
    m_CopyPasteComponent->SetOwnerElement(pOwnerElement);
    return true;
}

OwnerPtr<IPasteHelper> SectionViewSymbolNewCopyPasteComponent::GetPasteHelper() const
{
    return m_CopyPasteComponent->GetPasteHelper();
}

void SectionViewSymbolNewCopyPasteComponent::UpdateAfterCopy(const ICopyContext& copyContext)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_CopyPasteComponent, L"m_CopyPasteComponent为空",L"GDMPLab",L"2024-03-30");
    m_CopyPasteComponent->UpdateAfterCopy(copyContext);
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pOwnerElement, L"m_pOwnerElement为空",L"GDMPLab",L"2024-03-30");

    const IGenericElement* pGenericElement = quick_cast<const IGenericElement>(GetOwnerElement());
    DBG_WARN_AND_RETURN_VOID_UNLESS(pGenericElement, L"pGenericElement为空",L"GDMPLab",L"2024-03-30");
    const SectionViewSymbolNew* pSectionViewSymbolN = quick_cast<const SectionViewSymbolNew>(pGenericElement->GetExternalObject());
    DBG_WARN_AND_RETURN_VOID_UNLESS(pSectionViewSymbolN, L"pModelLine为空",L"GDMPLab",L"2024-03-30");
    IModelView* pModelView = pSectionViewSymbolN->GetSectionModelView();

    std::wstring viewName;
    bool bOk = GbmpModelViewUtil::GetNextModelViewName(m_pOwnerElement->GetDocument(), SectionViewType, L"剖面", L" ", viewName);
    DBG_WARN_AND_RETURN_VOID_UNLESS(bOk, L"GetNextModelViewName失败",L"GDMPLab",L"2024-03-30");
    pModelView->SetName(viewName);

    DBG_WARN_AND_RETURN_VOID_UNLESS(pModelView->GetCopyPasteComponent(), L"pModelView->GetCopyPasteComponent()为空",L"GDMPLab",L"2024-03-30");
    pModelView->GetCopyPasteComponent()->UpdateAfterCopy(copyContext);
}

void SectionViewSymbolNewCopyPasteComponent::UpdateForWeakParentCopied(const IDocument* pDocFrom, const IElement* pSource, const IElement* pCopy) const
{
    m_CopyPasteComponent->UpdateForWeakParentCopied(pDocFrom, pSource, pCopy);
}

bool SectionViewSymbolNewCopyPasteComponent::ShouldBeCopiedTogether(const ICopyContext & copyContext) const
{
    return m_CopyPasteComponent->ShouldBeCopiedTogether(copyContext);
}

bool SectionViewSymbolNewCopyPasteComponent::IsStrongParentsNeedCopied() const
{
    return m_CopyPasteComponent->IsStrongParentsNeedCopied();
}

bool SectionViewSymbolNewCopyPasteComponent::CanBeCopied(std::wstring* pErrorMessage) const
{
    return m_CopyPasteComponent->CanBeCopied(pErrorMessage);
}

#pragma endregion CopyPasteComponent


